package com.imiku.service;

import com.imiku.model.AuthUserFactory;
import com.imiku.model.UserInfo;
import com.imiku.repository.RoleInfoRepository;
import com.imiku.repository.UserInfoRepository;
import com.imiku.vo.PageVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
public class UserInfoService implements UserDetailsService {

    @Autowired
    private UserInfoRepository userInfoRepository;
    @Autowired
    private RoleInfoRepository roleInfoRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserInfo user = userInfoRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username));
        }
        List<String> roleInfoList = roleInfoRepository.findByUserId(user.getUserId());
        user.setRoles(roleInfoList);
        return AuthUserFactory.create(user);
    }

    public Page<UserInfo> findByPage(PageVo pageVo) {
        Pageable pageable = PageRequest.of(pageVo.getPageNumber(), pageVo.getPageSize(), Sort.by(Sort.Direction.DESC, "createDate"));
        return userInfoRepository.findAll(pageable);
    }

    public UserInfo findByUserId(int userId) {
        return userInfoRepository.findByUserId(userId);
    }

    public void save(UserInfo userInfo) {
        userInfo.setCreateDate(new Date());
        userInfo.setPassword(passwordEncoder().encode(userInfo.getPassword()));
        userInfoRepository.save(userInfo);
    }

    public void update(UserInfo userInfo) {
        if (StringUtils.isNoneBlank(userInfo.getPassword())) {
            userInfo.setPassword(passwordEncoder().encode(userInfo.getPassword()));
        }
        userInfoRepository.save(userInfo);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
